package com.yzdbx.individualtask;

import cn.hutool.core.collection.CollectionUtil;
import com.yzdbx.utils.DbUtil;
import com.yzdbx.utils.GenUtil;

import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

public class PurchaseShouHuoReGen {
    public static void main(String[] args) throws Exception {
        // 处理日期参数
        String startDate = "2025-07-01";
        String endDate =  "2025-07-10";
        if (args.length >= 2) {
            startDate = args[0];
            endDate = args[1];
            System.out.println("指定生成日期范围: " + startDate + " 到 " + endDate);
        } else if (args.length == 1) {
            startDate = args[0];
            endDate = args[0];
            System.out.println("指定生成日期: " + startDate);
        } else {
            System.out.println("未指定日期，将全量生成采购到货数据");
        }

        // 初始化 GenUtil 的日期信息
        LocalDate currentDate = LocalDate.now();
        if (startDate != null) {
            currentDate = LocalDate.parse(startDate);
        }
        GenUtil.setCurDate(currentDate);
        GenUtil.setCurTimeStamp(new Timestamp(currentDate.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli()));

        Connection connection = DbUtil.getConnection();
        boolean originalAutoCommit = true;
        try {
            originalAutoCommit = connection.getAutoCommit();
            connection.setAutoCommit(false);

            // 可选：清理历史数据（如需重置，取消注释）
            // connection.prepareStatement("DELETE FROM purchaseOfManifests").executeUpdate();
            // connection.prepareStatement("DELETE FROM ck03Listing WHERE documentType = '采购入库'").executeUpdate();
            // connection.prepareStatement("DELETE FROM ck04ListOfEntriesListOfEntries WHERE linkToList IN (SELECT id FROM ck03Listing WHERE documentType = '采购入库')").executeUpdate();
            // connection.commit();

            // 查询采购订单ID（根据日期范围过滤）
            List<Integer> purchaseIds = new ArrayList<>();
            String purchaseQuery;
            PreparedStatement stmt;
            if (startDate != null && endDate != null) {
                if (startDate.equals(endDate)) {
                    purchaseQuery = "SELECT id FROM cgPurchaseOrderForms WHERE DATE(dateOfProcurement) = ?";
                    stmt = connection.prepareStatement(purchaseQuery);
                    stmt.setString(1, startDate);
                } else {
                    purchaseQuery = "SELECT id FROM cgPurchaseOrderForms WHERE DATE(dateOfProcurement) BETWEEN ? AND ?";
                    stmt = connection.prepareStatement(purchaseQuery);
                    stmt.setString(1, startDate);
                    stmt.setString(2, endDate);
                }
            } else {
                purchaseQuery = "SELECT id FROM cgPurchaseOrderForms";
                stmt = connection.prepareStatement(purchaseQuery);
            }
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                purchaseIds.add(rs.getInt("id"));
            }
            rs.close();
            stmt.close();

            if (CollectionUtil.isEmpty(purchaseIds)) {
                System.out.println("没有找到采购订单数据，无法生成采购到货数据！");
                return;
            }
            System.out.println("找到 " + purchaseIds.size() + " 个采购订单，准备生成采购到货数据");

            int daohuoId = getMaxId(connection, "purchaseOfManifests");
            int ckdId = getMaxId(connection, "ck03Listing");
            int ckmxId = getMaxId(connection, "ck04ListOfEntriesListOfEntries");

            String manifestSql = "insert into purchaseOfManifests (id,purchaseOfManifestNumber,dateOfArrival,consignee,clientInformation,totalArrivals,amountOfGoodsToBeDelivered,synchronisingFolderFailedSS,created,approvalStatus,associatedPurchaseOrderInformati) values (?,?,?,?,?,?,?,?,?,?,?)";
            String ckmxSql = "insert into ck04ListOfEntriesListOfEntries(id,productInformation,numberOfEntries,linkToList) values (?,?,?,?)";
            String ckdSql = "insert into ck03Listing (id,repositoryNumber,operator,repositoryDate,approvalStatus,associatedSuppliers,documentType) values (?,?,?,?,?,?,?)";

            try (PreparedStatement manifestStatement = connection.prepareStatement(manifestSql);
                 PreparedStatement ckmxStatement = connection.prepareStatement(ckmxSql);
                 PreparedStatement ckdStatement = connection.prepareStatement(ckdSql)) {

                int batchCount = 0;
                final int BATCH_SIZE = 3;
                // 按天维护采购到货单号计数器
                Map<String, Integer> dateToNo = new HashMap<>();
                for (int i = 1; i <= purchaseIds.size(); i++) {
                    final int currentIndex = i - 1;
                    int curId = daohuoId + i;
                    // 查询采购订单
                    Map<String, Object> saleOrder = DbUtil.getById(connection, "cgPurchaseOrderForms", purchaseIds.get(currentIndex));

                    // 获取采购订单的到货日期，并动态设置 GenUtil 日期
                    java.sql.Date procurementDate = (java.sql.Date) saleOrder.get("dateOfProcurement");
                    if (procurementDate != null) {
                        LocalDate localDate = procurementDate.toLocalDate();
                        GenUtil.setCurDate(localDate);
                        GenUtil.setCurTimeStamp(new Timestamp(procurementDate.getTime()));
                    }
                    // 生成当天自增的采购到货单号
                    String dateStr = procurementDate != null ? procurementDate.toString().replace("-", "") : "00000000";
                    int currentNo = dateToNo.getOrDefault(dateStr, 0) + 1;
                    dateToNo.put(dateStr, currentNo);
                    String daohuodanhao = "CGDH" + dateStr + String.format("%04d", currentNo);

                    // 查询采购订单明细
                    List<LinkedHashMap<String, Object>> details;
                    try (PreparedStatement statement = connection.prepareStatement("select * from breakdownOfPurchaseOrders where associatedPurchaseOrders = ?")) {
                        statement.setInt(1, purchaseIds.get(currentIndex));
                        ResultSet resultSet = statement.executeQuery();
                        details = DbUtil.resultSetToList(resultSet);
                    }

                    List<LinkedHashMap<String, Object>> associatedPurchase = details.stream()
                            .filter(cur -> cur.get("associatedPurchaseOrders").equals(purchaseIds.get(currentIndex)))
                            .collect(Collectors.toList());

                    int totalArrivals = 0;
                    BigDecimal totalAmount = BigDecimal.ZERO;

                    // 创建入库明细
                    for (int j = 1; j <= associatedPurchase.size(); j++) {
                        LinkedHashMap<String, Object> orderDetail = associatedPurchase.get(j - 1);
                        int quantity = Integer.parseInt(orderDetail.get("procurementVolume").toString());
                        BigDecimal unitPrice = BigDecimal.valueOf(Double.parseDouble(orderDetail.get("unitPrice").toString()));

                        totalArrivals += quantity;
                        totalAmount = totalAmount.add(unitPrice.multiply(BigDecimal.valueOf(quantity)));

                        int curCkmxId = ++ckmxId;
                        ckmxStatement.setInt(1, curCkmxId);
                        ckmxStatement.setInt(2, Integer.parseInt(orderDetail.get("procurementInformation").toString()));
                        ckmxStatement.setInt(3, quantity);
                        ckmxStatement.setInt(4, ckdId + i);
                        ckmxStatement.addBatch();
                    }

                    // 创建收货单
                    manifestStatement.setInt(1, curId);
                    manifestStatement.setString(2, daohuodanhao);
                    manifestStatement.setTimestamp(3, GenUtil.CUR_TIME_STAMP.get());
                    manifestStatement.setString(4, saleOrder.get("synchronisingFolderFailedSS").toString());
                    manifestStatement.setInt(5, Integer.parseInt(saleOrder.get("associatedSuppliers").toString()));
                    manifestStatement.setInt(6, totalArrivals);
                    manifestStatement.setBigDecimal(7, totalAmount);
                    manifestStatement.setString(8, saleOrder.get("synchronisingFolderFailedSS").toString());
                    manifestStatement.setTimestamp(9, GenUtil.CUR_TIME_STAMP.get());
                    manifestStatement.setString(10, "已通过");
                    manifestStatement.setInt(11, Integer.parseInt(saleOrder.get("id").toString()));
                    manifestStatement.addBatch();

                    // 创建入库单
                    ckdStatement.setInt(1, ckdId + i);
                    ckdStatement.setString(2, GenUtil.getNo("RK", i));
                    ckdStatement.setString(3, saleOrder.get("synchronisingFolderFailedSS").toString());
                    ckdStatement.setTimestamp(4, GenUtil.CUR_TIME_STAMP.get());
                    ckdStatement.setString(5, "已通过");
                    ckdStatement.setInt(6, Integer.parseInt(saleOrder.get("associatedSuppliers").toString()));
                    ckdStatement.setString(7, "采购入库");
                    ckdStatement.addBatch();

                    System.out.println("生成采购到货单: " + daohuodanhao + "，采购订单ID: " + saleOrder.get("id") + "，到货数量: " + totalArrivals + "，到货金额: " + totalAmount);

                    batchCount++;
                    if (batchCount >= BATCH_SIZE) {
                        manifestStatement.executeBatch();
                        ckmxStatement.executeBatch();
                        ckdStatement.executeBatch();
                        connection.commit();
                        batchCount = 0;
                    }
                }

                // 执行剩余的批量插入
                if (batchCount > 0) {
                    manifestStatement.executeBatch();
                    ckmxStatement.executeBatch();
                    ckdStatement.executeBatch();
                    connection.commit();
                }
            }
            System.out.println("采购到货数据生成完成，共生成 " + purchaseIds.size() + " 条记录");
        } catch (Exception e) {
            try {
                if (!connection.getAutoCommit()) {
                    connection.rollback();
                }
            } catch (SQLException ex) {
                throw new RuntimeException("回滚失败", ex);
            }
            throw new RuntimeException("数据生成失败", e);
        } finally {
            try {
                connection.setAutoCommit(originalAutoCommit);
            } catch (SQLException e) {
                throw new RuntimeException("恢复自动提交状态失败", e);
            }
            DbUtil.closeConnection(connection);
        }
    }

    private static int getMaxId(Connection connection, String table) throws SQLException {
        try (Statement stmt = connection.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT MAX(id) FROM " + table)) {
            if (rs.next()) {
                return rs.getInt(1);
            }
        }
        return 0;
    }
} 